package com.geeguo.ebuilder.operation.controller.system.dictionary;

import com.geeguo.ebuilder.core.common.action.ActionResult;
import com.geeguo.ebuilder.core.common.dictionary.ExtendEnumField;
import com.geeguo.ebuilder.core.common.dictionary.IDictionary;
import com.geeguo.ebuilder.core.security.annotation.RequiresLogin;
import com.geeguo.ebuilder.operation.business.system.dictionary.model.DictionaryVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.reflections.Reflections;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;
import java.util.*;

@Tag(name = "数据字典信息")
@RestController
@Slf4j
public class DictionaryController implements InitializingBean {

    private static Map<String, List<DictionaryVO>> dictionaryMapping = null;

    @Override
    public void afterPropertiesSet() throws Exception {
        dictionaryMapping = getDictionaryMapping();
    }

    @Operation(summary = "获取所有数据字典")
    @GetMapping("/system/dictionary/getAll")
    @RequiresLogin
    public ActionResult<Map<String, List<DictionaryVO>>> getAll() {
        return ActionResult.success(dictionaryMapping);
    }

    private Map<String, List<DictionaryVO>> getDictionaryMapping() throws IllegalAccessException {
        Map<String, List<DictionaryVO>> mapping = new HashMap<>();
        List<DictionaryVO> dictionaryList;
        DictionaryVO dictionaryVO;

        for (Class<? extends IDictionary> dicEnum : getDictionarySet()) {
            int begin = dicEnum.getName().lastIndexOf(".") + 1;
            int end = dicEnum.getName().lastIndexOf("Enum");
            String key = dicEnum.getName().substring(begin, end);
            dictionaryList = new ArrayList<>();

            Field[] fields = dicEnum.getDeclaredFields();
            for (IDictionary item : dicEnum.getEnumConstants()) {
                Map<String, Object> extend = new HashMap<>();
                for (Field field : fields) {
                    String fieldName = field.getName();
                    if (field.getAnnotation(ExtendEnumField.class) != null) {
                        Type genericType = field.getGenericType();
                        String getMethod = (genericType.getTypeName().contains("boolean") ? "is" : "get") + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
                        try {
                            Object obj = dicEnum.getMethod(getMethod).invoke(item);
                            extend.put(fieldName, obj);
                        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                            log.error(e.getMessage(), e);
                        }
                    }
                }
                dictionaryVO = new DictionaryVO();
                dictionaryVO.setValue(item.getValue());
                dictionaryVO.setLabel(item.getLabel());
                if (MapUtils.isNotEmpty(extend)) {
                    dictionaryVO.setExtend(extend);
                }
                dictionaryList.add(dictionaryVO);
            }
            mapping.put(key, dictionaryList);
        }
        return mapping;
    }

    private Set<Class<? extends IDictionary>> getDictionarySet() {
        Reflections reflections = new Reflections("com.geeguo.ebuilder.core.common.dictionary", "com.geeguo.ebuilder.operation.base.core.dictionary");
        return reflections.getSubTypesOf(IDictionary.class);
    }
}